package net.jueb.frameWorkDemo.mvc4mod.mapper;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Arg;
import org.apache.ibatis.annotations.ConstructorArgs;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;

/**
 * mybatis3.3.1版本新增功能
 * 官方文档地址:http://www.mybatis.org/mybatis-3/zh/index.html
 * @author juebanlin
 */
public interface Mybatis3_3_1_Mapper {

	class TestObj{
		
	}
	
	/**
	 * 这个例子展示了如何使用 @SelectKey 注解来在插入前读取数据库序列的值：
	 * @param name
	 * @return
	 */
	@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
	@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
	int insertTable3(Object name);
	
	/**
	 * 这个例子展示了如何使用 @SelectKey 注解来在插入后读取数据库识别列的值：
	 * @param name
	 * @return
	 */
	@Insert("insert into table2 (name) values(#{name})")
	@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
	int insertTable2(Object name);
	
	@Results(id = "userResult", value = {
			  @Result(property = "id", column = "uid", id = true),
			  @Result(property = "firstName", column = "first_name"),
			  @Result(property = "lastName", column = "last_name")
			})
	@Select("select * from users where id = #{id}")
	User getUserById(Integer id);

	@Results(id = "companyResults")
	@ConstructorArgs({
//		@Arg(property = "id", column = "cid", id = true),
//		@Arg(property = "name", column = "name")
	})
	@Select("select * from company where id = #{id}")
	TestObj getById(Integer id);	
	
	
	public class City2 {
	    private Integer id;

	    private String cityName;

	    private String cityState;

	    public City2() {
	    }

	    public City2(String cityName, String cityState) {
	        this.cityName = cityName;
	        this.cityState = cityState;
	    }

	    //省略setter,getter
	    @Override
	    public String toString() {
	        return "City2{" +
	                "id=" + id +
	                ", cityName='" + cityName + '\'' +
	                ", cityState='" + cityState + '\'' +
	                '}';
	    }
	}
	
    /**
     * 批量插入方式1
     * @param cities
     * @return
     */
    @Insert("<script>" +
            "insert into city (id, name, state) values " +
            "<foreach collection=\"list\" item=\"city\" separator=\",\" >" +
                "(#{city.id}, #{city.cityName}, #{city.cityState})" +
            "</foreach>" +
            "</script>")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertCities(List<City2> cities);

    /**
     * 根据主键查询一个
     * @param id
     * @return
     */
    @Results(id = "cityResult", value = {
        @Result(property = "id", column = "id", id = true),
        @Result(property = "cityName", column = "name", id = true),
        @Result(property = "cityState", column = "state", id = true)
    })
    @Select("select id, name, state from city where id = #{id}")
    City2 selectByCityId(Integer id);

    /**
     * 查询全部，引用上面的Results
     * 
     * @return
     */
    @ResultMap("cityResult")
    @Select("select id, name, state from city")
    List<City2> selectAll();
    
    /**
     * 第二张批量插入方式
     * @param users
     */
    @InsertProvider(type = UserDAOProvider.class, method = "insertAll")  
    void insertAll(List<City2> users);  
    
    public class UserDAOProvider {  
    	
    	/**
    	 * MyBatis会把UserDAO的insertAll方法中的List类型的参数存入一个Map中, 
    	 * 默认的key是"list", 可以用@Param注解自定义名称, 
    	 * MyBatis在调用@InsertProvide指定的方法时将此map作为参数传入, 
    	 * 所有代码中使用List<User> users = (List<User>) map.get("list");获取list参数. 
    	 * @param map
    	 * @return
    	 */
        public String insertAll(Map<?,?> map) {  
            @SuppressWarnings("unchecked")
			List<User> users = (List<User>) map.get("list");  
            StringBuilder sb = new StringBuilder();  
            sb.append("INSERT INTO User ");  
            sb.append("(id, name) ");  
            sb.append("VALUES ");  
            MessageFormat mf = new MessageFormat("(null, #'{'list[{0}].name})");  
            for (int i = 0; i < users.size(); i++) {  
                sb.append(mf.format(new Object[]{i}));  
                if (i < users.size() - 1) {  
                    sb.append(",");  
                }  
            }  
            return sb.toString();  
        }  
    }
    
    public class User {  
        private Integer id;  
        private String name;  
      
        public Integer getId() {  
          
            return id;  
        }  
      
        public void setId(Integer id) {  
            this.id = id;  
        }  
          
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
    } 
}
